// 思路：1.让前面的指针先移动n步，之后前后指针共同移动直到前面的指针到尾部为止
//         前指针为 start，后指针为 end，二者都等于 head
//      2.start 先向前移动n步
//        之后 start 和 end 共同向前移动，此时二者的距离为 n，当 start 到尾部时，end 的位置恰好为倒数第 n 个节点
//      3.因为要删除该节点，所以要移动到该节点的前一个才能删除，所以循环结束条件为 start.next != null
//       删除后返回 head.next，为什么不直接返回 head 呢，因为 head 有可能是被删掉的点

class ListNode {
    val: number
    next: ListNode | null
    constructor(val?: number, next?: ListNode | null) {
        this.val = (val === undefined ? 0 : val)
        this.next = (next === undefined ? null : next)
    }
}

function removeNthFromEnd(head: ListNode | null, n: number): ListNode | null {
    let dummy = new ListNode();
    dummy.next = head;
    let n1 = dummy;
    let n2 = dummy;
    for (let i = 0; i <= n; i++) {
        n2 = n2.next;
    }
    while (n2 !== null) {
        n1 = n1.next;
        n2 = n2.next;
    }
    n1.next = n1.next.next;
    return dummy.next;
};